package com.jiwei.community.utils;

import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
import com.jiwei.community.constants.SystemConstant;
import com.jiwei.community.dao.UserCommunityLevelMapper;
import com.jiwei.community.entity.Post;
import com.jiwei.community.enums.AppHttpCodeEnum;
import com.jiwei.community.exception.SystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * 用户对帖子的评分：点赞+收藏+浏览+回复
 * 用户相似度=帖子评分相似度+社区相似度
 * 社区相似度=是否为相同社区
 * 两个用户相同正反馈帖子的评分数组x,y
 * 皮尔森相关系数=(x和y的协方差)/(x的标准差*y的标准差)
 *
 * select a.post_id,a.user_id as x_user_id,b.user_id as y_user_id ,a.score as x_score,b.score as y_score  from user_post_score as a
 * inner join user_post_score as b
 * where a.post_id = b.post_id and a.user_id != b.user_id
 *
 * 查询当前用户与其他用户所拥有的相同正反馈帖子的各自评分列表
 * select a.user_id as x_user_id
 * ,b.user_id as y_user_id
 * ,GROUP_CONCAT(a.post_id) post_id_list
 * ,GROUP_CONCAT(a.score) as x_score_list
 * ,GROUP_CONCAT(b.score) as y_score_list
 * from user_post_score as a
 * inner join user_post_score as b
 * where a.post_id = b.post_id and a.user_id != b.user_id and a.user_id = 1
 * group by b.user_id
 *
 * 查询所有用户与其他用户所拥有的相同正反馈帖子的各自评分列表
 * select a.user_id as x_user_id
 * ,b.user_id as y_user_id
 * ,GROUP_CONCAT(a.post_id) post_id_list
 * ,GROUP_CONCAT(a.score) as x_score_list
 * ,GROUP_CONCAT(b.score) as y_score_list
 * from user_post_score as a
 * inner join user_post_score as b
 * where a.post_id = b.post_id and a.user_id != b.user_id
 * group by b.user_id, a.user_id
 *
 * 查询指定两个用户加入的相同社区数量
 * select count(*)
 * from user_community_level as ucl1
 * inner join user_community_level as ucl2
 * where ucl1.community_id = ucl2.community_id and ucl1.user_id != ucl2.user_id and ucl1.user_id = 1 and ucl2.user_id = 3;
 *
 *
 *
 * @author 季伟
 * @date 2024/4/3
 */

public class RecommendUtils {
    public static DecimalFormat format = new DecimalFormat("0.##");
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    UserCommunityLevelMapper userCommunityLevelMapper;
    public static void main(String[] args) {
        List<Double> x = Arrays.asList(1.0,2.5,3.0);
        List<Double> y = Arrays.asList(2.0,3.0,5.0);
        System.out.println(getScoreSimilarity(x,y));

    }


    public static Double getScoreSimilarity(List<Double> xScore,List<Double> yScore){
        Double xAverage = getAverage(xScore);
        Double yAverage = getAverage(yScore);
        Double similarity = getNumerator(xScore,yScore,xAverage,yAverage)/getDenominator(xScore,yScore,xAverage,yAverage);
        return Math.abs(similarity);
    }
    private static Double getAverage(List<Double> list){
        double sum = 0.0;
        for (Double i : list){
            sum+=i;
        }
        return sum/list.size();
    }

    /**
     * 计算分子
     * @param x
     * @param y
     * @param xAverage
     * @param yAverage
     * @return
     */
    private static Double getNumerator(List<Double> x,List<Double> y,Double xAverage,Double yAverage){
        if (x.size() != y.size())throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR,"推荐出错");
        double numerator = 0.0;
        for (int i=0;i<x.size();i++){
            numerator += (x.get(i)-xAverage)*(y.get(i)-yAverage);
        }
        return numerator;
    }

    /**
     * 计算分母
     * @param x
     * @param y
     * @param xAverage
     * @param yAverage
     * @return
     */
    private static Double getDenominator(List<Double> x,List<Double> y,Double xAverage,Double yAverage){
        if (x.size() != y.size())throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR,"推荐出错");
        double xUnit = 0.0;
        for (Double xi : x) {
            xUnit += (xi - xAverage) * (xi - xAverage);
        }
        double yUnit = 0.0;
        for (Double yi : y){
            yUnit += (yi-yAverage)*(yi-yAverage);
        }
        Double denominator = Math.sqrt(xUnit*yUnit);
        if (denominator == 0)throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR,"推荐算法失效");
        return denominator;
    }



}
